home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / muds / mordor_2.000 / mordor_2 / src / update.c < prev    next >
C/C++ Source or Header  |  1995-06-25  |  24KB  |  816 lines

  1. /*
  2.  * UPDATE.C:
  3.  *
  4.  *  Routines to handle non-player game updates.
  5.  *
  6.  *  Copyright (C) 1991, 1992, 1993 Brett J. Vickers
  7.  *
  8.  */
  9.  
  10. #include "mstruct.h"
  11. #include "mextern.h"
  12. #include "update.h"
  13.  
  14. static long last_update;
  15. static long last_user_update;
  16. static long last_random_update;
  17. static long last_active_update;
  18. static long last_time_update;
  19. static long last_shutdown_update;
  20.  
  21. static long last_allcmd;
  22.  
  23. long        last_exit_update;
  24. long        TX_interval = 4200;
  25. short       Random_update_interval = 20;
  26.  
  27. static ctag *first_active;
  28. extern void update_allcmd();
  29.  
  30. /**********************************************************************/
  31. /*              update_game               */
  32. /**********************************************************************/
  33.  
  34. /* This function handles all the updates that occur while players are */
  35. /* typing.                                */
  36.  
  37. void update_game()
  38. {
  39.     long    t;
  40.  
  41.     t = time(0);
  42.     if(t == last_update)
  43.         return;
  44.  
  45.     last_update = t;
  46.     if(t - last_user_update >= 20)
  47.         update_users(t);
  48.     if(t - last_random_update >= Random_update_interval)
  49.         update_random(t);
  50.     if(t != last_active_update)
  51.         update_active(t);
  52.     if(t - last_time_update >= 150)
  53.         update_time(t);
  54.     if(t - last_exit_update >= TX_interval)
  55.         update_exit(t);
  56.     if(Shutdown.ltime && t - last_shutdown_update >= 30)
  57.         if(Shutdown.ltime + Shutdown.interval <= t+500)
  58.             update_shutdown(t);
  59.  
  60. #ifdef RECORD_ALL
  61.     if(t- last_allcmd >= 300)
  62.      update_allcmd(t);
  63. #endif RECORD_ALL
  64. }
  65.  
  66. /**********************************************************************/
  67. /*              update_users                  */
  68. /**********************************************************************/
  69.  
  70. /* This function controls user updates.  Every 20 seconds it checks a */
  71. /* user's time-out flags (such as invisibility, etc.) and it also     */
  72. /* checks for excessive idle times.  If a user has been idle for over */
  73. /* 30 mins, he is disconnected.                       */
  74.  
  75. void update_users(t)
  76. long    t;
  77. {
  78.     int i;
  79.     last_user_update = t;
  80.  
  81.     for(i=0; i<Tablesize; i++) {
  82.         if(!Ply[i].io) continue;
  83.         if(Ply[i].ply && Ply[i].ply->class == DM) continue;
  84.         if(t - Ply[i].io->ltime > 300 && Ply[i].io->fn != waiting) {
  85.             write(i, "\n\rTimed out.\n\r", 14);
  86.             disconnect(i);
  87.             continue;
  88.         }
  89.  
  90.         if(!Ply[i].ply) continue;
  91.         if(Ply[i].ply->fd < 0) continue;
  92.         update_ply(Ply[i].ply); 
  93.     }
  94. }
  95.  
  96. /**********************************************************************/
  97. /*              update_random                 */
  98. /**********************************************************************/
  99.  
  100. /* This function checks all player-occupied rooms to see if random monsters */
  101. /* have entered them.  If it is determined that random monster should enter */
  102. /* a room, it is loaded and items it is carrying will be loaded with it.    */
  103.  
  104. void update_random(t)
  105. long    t;
  106. {
  107.     creature    *crt_ptr;
  108.     object      *obj_ptr;
  109.     room        *rom_ptr;
  110.     int     check[PMAX];
  111.     int     num, m, n, i, j, k, l, total = 0;
  112.  
  113.     last_random_update = t;
  114.     for(i=0; i<Tablesize; i++) {
  115.         if(!Ply[i].ply || !Ply[i].io) continue;
  116.         if(Ply[i].ply->fd < 0) continue;
  117.  
  118.         rom_ptr = Ply[i].ply->parent_rom;
  119.  
  120.         for(j=0; j<total; j++)
  121.             if(check[j] == rom_ptr->rom_num) break;
  122.         if(j < total) continue;
  123.  
  124.         check[total++] = rom_ptr->rom_num;
  125.  
  126.         if(mrand(1,100) > rom_ptr->traffic) continue;
  127.  
  128.         n = mrand(0,9);
  129.         if(!rom_ptr->random[n]) continue;
  130.         m = load_crt(rom_ptr->random[n], &crt_ptr);
  131.         if(m < 0) continue;
  132.  
  133.         if(F_ISSET(rom_ptr, RPLWAN))
  134.             num = mrand(1, count_ply(rom_ptr));
  135.         else if(crt_ptr->numwander > 1)
  136.             num = mrand(1, crt_ptr->numwander);
  137.         else
  138.             num = 1;
  139.  
  140.         for(l=0; l<num; l++) {
  141.             crt_ptr->lasttime[LT_ATTCK].ltime = 
  142.             crt_ptr->lasttime[LT_MSCAV].ltime =
  143.             crt_ptr->lasttime[LT_MWAND].ltime = t;
  144.  
  145.             if(crt_ptr->dexterity < 20)
  146.                 crt_ptr->lasttime[LT_ATTCK].interval = 3;
  147.             else
  148.                 crt_ptr->lasttime[LT_ATTCK].interval = 2;
  149.  
  150.             j = mrand(1,100);
  151.             if(j<90) j=1;
  152.             else if(j<96) j=2;
  153.             else j=3;
  154.             for(k=0; k<j; k++) {
  155.                 m = mrand(0,9);
  156.                 if(crt_ptr->carry[m]) {
  157.                     m=load_obj(crt_ptr->carry[m],
  158.                         &obj_ptr);
  159.                     if(m > -1) {
  160.                         if(F_ISSET(obj_ptr, ORENCH))
  161.                             rand_enchant(obj_ptr);
  162.                         obj_ptr->value =
  163.                         mrand((obj_ptr->value*9)/10,
  164.                               (obj_ptr->value*11)/10);
  165.                         add_obj_crt(obj_ptr, crt_ptr);
  166.                     }
  167.                 }
  168.             }
  169.  
  170.             if(!F_ISSET(crt_ptr, MNRGLD) && crt_ptr->gold)
  171.                 crt_ptr->gold =
  172.                 mrand(crt_ptr->gold/10, crt_ptr->gold);
  173.  
  174.             if(!l) 
  175.                 add_crt_rom(crt_ptr, rom_ptr, num);
  176.             else
  177.                 add_crt_rom(crt_ptr, rom_ptr, 0);
  178.  
  179.             add_active(crt_ptr);
  180.             if(l != num-1)
  181.                 load_crt(rom_ptr->random[n], &crt_ptr);
  182.         }
  183.     }
  184. }
  185.  
  186. /************************************************************************/
  187. /*              update_active               */
  188. /************************************************************************/
  189.  
  190. /* This function updates the activities of all monsters who are currently */
  191. /* active (ie. monsters on the active list).  Usually this is reserved    */
  192. /* for monsters in rooms that are occupied by players.            */
  193.  
  194. void update_active(t)
  195. long    t;
  196. {
  197.     creature    *crt_ptr, *att_ptr;
  198.     object      *obj_ptr;
  199.     room        *rom_ptr;
  200.     ctag        *cp;
  201.     char        *enemy;
  202.     long        i,z;
  203.     int     rtn = 0, n, fd, p=0;
  204.  
  205.     last_active_update = t;
  206.     if(!(cp = first_active)) return;
  207.     while(cp) {
  208.         if(!cp) break;
  209.  
  210.         crt_ptr = cp->crt;
  211.         rom_ptr = crt_ptr->parent_rom;
  212.  
  213.         if(!rom_ptr->first_ply) {
  214.             del_active(crt_ptr);
  215.             cp = first_active;
  216.             continue;
  217.         }
  218.  
  219.         i = LT(crt_ptr, LT_ATTCK);
  220.         if(i > t) {
  221.             cp = cp->next_tag;
  222.             continue;
  223.         }
  224.  
  225.         i = LT(crt_ptr, LT_HEALS);
  226.         while(i <= t && (crt_ptr->hpcur < crt_ptr->hpmax ||
  227.               crt_ptr->mpcur < crt_ptr->mpmax)) {
  228.             crt_ptr->hpcur += MAX(1,crt_ptr->hpmax/10);
  229.             if(crt_ptr->hpcur > crt_ptr->hpmax)
  230.                 crt_ptr->hpcur = crt_ptr->hpmax;
  231.             crt_ptr->mpcur += MAX(1,crt_ptr->mpmax/6);
  232.             if(crt_ptr->mpcur > crt_ptr->mpmax)
  233.                 crt_ptr->mpcur = crt_ptr->mpmax;
  234.             i += 60L;
  235.             crt_ptr->lasttime[LT_HEALS].ltime = t;
  236.             crt_ptr->lasttime[LT_HEALS].interval = 60L;
  237.         }
  238.     if (t > LT(crt_ptr, LT_CHRMD)&&F_ISSET(crt_ptr, MCHARM))
  239.         F_CLR(crt_ptr, MCHARM);
  240.  
  241.         crt_ptr->lasttime[LT_ATTCK].ltime = t;
  242.         if(crt_ptr->dexterity < 20)
  243.             crt_ptr->lasttime[LT_ATTCK].interval = 3;
  244.         else
  245.             crt_ptr->lasttime[LT_ATTCK].interval = 2;
  246.  
  247.         if(F_ISSET(crt_ptr, MSCAVE)) {
  248.             i = crt_ptr->lasttime[LT_MSCAV].ltime;
  249.             if(t-i > 20 && mrand(1,100) <= 15 && 
  250.                rom_ptr->first_obj && 
  251.                !F_ISSET(rom_ptr->first_obj->obj, ONOTAK) &&
  252.                !F_ISSET(rom_ptr->first_obj->obj, OSCENE) &&
  253.                !F_ISSET(rom_ptr->first_obj->obj, OHIDDN) &&
  254.                !F_ISSET(rom_ptr->first_obj->obj, OPERM2) &&
  255.                !F_ISSET(rom_ptr->first_obj->obj, OPERMT)) {
  256.                 obj_ptr = rom_ptr->first_obj->obj;
  257.                 del_obj_rom(obj_ptr, rom_ptr);
  258.                 add_obj_crt(obj_ptr, crt_ptr);
  259.                 F_SET(crt_ptr, MHASSC);
  260.                 broadcast_rom(-1, crt_ptr->rom_num,
  261.                           "%M picked up %1i.", 
  262.                           crt_ptr, obj_ptr);
  263.             }
  264.             if(t-i > 20)
  265.                 crt_ptr->lasttime[LT_MSCAV].ltime = t;
  266.         }
  267.  
  268.         if(!F_ISSET(crt_ptr, MHASSC) && !F_ISSET(crt_ptr, MPERMT) && !F_ISSET(crt_ptr, MDMFOL)) {
  269.             i = crt_ptr->lasttime[LT_MWAND].ltime;
  270.             if(t-i > 20 
  271.                && mrand(1,100) <= crt_ptr->parent_rom->traffic
  272.                && !crt_ptr->first_enm) {
  273.                 broadcast_rom(-1, crt_ptr->rom_num,
  274.                     "%1M just wandered away.",
  275.                     crt_ptr);
  276.                 del_crt_rom(crt_ptr, rom_ptr);
  277.                 del_active(crt_ptr);
  278.                 free_crt(crt_ptr);
  279.                 cp = first_active;
  280.                 continue;
  281.             }
  282.             if(t-i > 20)
  283.                 crt_ptr->lasttime[LT_MWAND].ltime = t;
  284.         }
  285.  
  286.     if(!crt_ptr->first_enm && (!F_ISSET(crt_ptr, MAGGRE) && 
  287.             !F_ISSET(crt_ptr, MGAGGR) && !F_ISSET(crt_ptr, MEAGGR))) {
  288.             cp = cp->next_tag;
  289.             continue;
  290.         }            
  291.         if(crt_ptr->first_enm) {
  292.             enemy = crt_ptr->first_enm->enemy;
  293.             att_ptr = find_crt(crt_ptr, rom_ptr->first_ply,
  294.                        enemy, 1);
  295.             if(!att_ptr) {
  296.                 if(!find_who(enemy))
  297.                     del_enm_crt(enemy, crt_ptr);
  298.                 else
  299.                     end_enm_crt(enemy, crt_ptr);
  300.             }
  301.             else {
  302.         if(is_charm_crt(crt_ptr->name, att_ptr)&& F_ISSET(crt_ptr, MCHARM))
  303.         p = 1;
  304.             crt_ptr->NUMHITS++;
  305.         n=20;
  306.             if(F_ISSET(crt_ptr, MMAGIO))
  307.          n=crt_ptr->proficiency[0];
  308.              
  309.         if(F_ISSET(crt_ptr, MMAGIC) && mrand(1, 100) <= n && !p) {
  310.                 rtn = crt_spell(crt_ptr, att_ptr);
  311.                 if(!rom_ptr->first_ply) {
  312.                     del_active(crt_ptr);
  313.                     cp = first_active;
  314.                     continue;
  315.                 }
  316.                 if(rtn == 2) {
  317.                     cp = first_active;
  318.                     continue;
  319.                 }
  320.                 else if(rtn == 1)
  321.                     n = 21;
  322.                 else n = crt_ptr->thaco - att_ptr->armor/10;
  323.             }
  324.  
  325.             else {
  326.                 n = crt_ptr->thaco - att_ptr->armor/10;
  327.                 n = MAX(n, 1);
  328.             }
  329.  
  330.             if(mrand(1,20) >= n && !p) {
  331.                 fd = att_ptr->fd;
  332.                 ANSI(fd, RED);
  333.  
  334. if(F_ISSET(crt_ptr, MBRETH) && mrand(1,30)<5) 
  335.     if (F_ISSET(crt_ptr, MBRWP1) && !F_ISSET(crt_ptr, MBRWP2))
  336.     {
  337.     print(fd, "%M spits acid on you!\n", crt_ptr);
  338.     broadcast_rom(fd, att_ptr->rom_num,
  339.        "%M spits acid on %M!", crt_ptr, att_ptr);
  340.         n = dice(crt_ptr->level, 3, 0);
  341.     }
  342.     else if (F_ISSET(crt_ptr, MBRWP1) && F_ISSET(crt_ptr, MBRWP2))
  343.     {
  344.     print(fd, "%M breathe poisonous gas on you!\n", crt_ptr);
  345.     broadcast_rom(fd, att_ptr->rom_num,
  346.        "%M breathes poisonous gas on %M!", crt_ptr, att_ptr);
  347.         n = dice(crt_ptr->level, 2, 1);
  348.         print(fd, "%M poisoned you.\n", crt_ptr);
  349.         F_SET(att_ptr, PPOISN);
  350.     }
  351.     else if (!F_ISSET(crt_ptr, MBRWP1) && F_ISSET(crt_ptr, MBRWP2))
  352.     {
  353.     print(fd, "%M breathe frost on you!\n", crt_ptr);
  354.     broadcast_rom(fd, att_ptr->rom_num,
  355.      "%M breathes frost on %M!", crt_ptr, att_ptr);
  356.     if(F_ISSET(att_ptr, PRCOLD))
  357.         n = dice(crt_ptr->level, 2, 0);
  358.     else
  359.         n = dice(crt_ptr->level, 4, 0);
  360.  
  361.     }
  362.     else{
  363.         print(fd, "%M breathe fire on you!\n", crt_ptr);
  364.         broadcast_rom(fd, att_ptr->rom_num,
  365.            "%M breathes fire on %M!", crt_ptr, att_ptr);
  366.             if(F_ISSET(att_ptr, PRFIRE))
  367.                 n = dice(crt_ptr->level, 2, 0);
  368.             else
  369.                 n = dice(crt_ptr->level, 4, 0);
  370.     }
  371. else
  372. {
  373.     if(F_ISSET(crt_ptr, MENEDR) && mrand(1,100)< 10) 
  374.     {
  375.         n = dice(crt_ptr->level, 5, (crt_ptr->level)*5);
  376.         n = MAX(0,MIN(n,att_ptr->experience));
  377.         print(fd, "%M drains your experience!\n", crt_ptr);
  378.         broadcast_rom(fd, att_ptr->rom_num,
  379.         "%M energy drains %M!", crt_ptr, att_ptr);
  380.         att_ptr->experience -= n;
  381.         lower_prof(att_ptr,n);
  382.         print(fd, "%M drains you for %d experience.\n",crt_ptr,n);
  383.     }
  384.  
  385.  
  386. n = mdice(crt_ptr);
  387. }
  388.                 att_ptr->hpcur -= n;
  389.                 print(fd, "%M hit you for %d damage.\n",
  390.                       crt_ptr, n);
  391.  
  392.                 if(F_ISSET(crt_ptr, MPOISS) && 
  393.                    mrand(1,100) <= 15) {
  394.                     print(fd, "%M poisoned you.\n",
  395.                           crt_ptr);
  396.                     F_SET(att_ptr, PPOISN);
  397.                 }
  398.  
  399.                 if(F_ISSET(crt_ptr, MDISEA) && 
  400.                    mrand(1,100) <= 15) {
  401.                     print(fd, "%M infects you.\n",
  402.                           crt_ptr);
  403.                     F_SET(att_ptr, PDISEA);
  404.                 }
  405.  
  406.         
  407.         if(F_ISSET(crt_ptr, MBLNDR) &&
  408.                    mrand(1,100) <= 15) {
  409.                     print(fd, "%M  blinds your eyes.\n",
  410.                           crt_ptr);
  411.                     F_SET(att_ptr, PBLIND);
  412.         }
  413.   
  414.                 if(F_ISSET(crt_ptr, MDISIT) && 
  415.                    mrand(1,100) <= 15) 
  416.                 dissolve_item(att_ptr,crt_ptr);
  417.                 
  418.  
  419.  
  420.                 ANSI(fd, WHITE);
  421.  
  422.                 n = choose_item(att_ptr);
  423.  
  424.                 if(n) {
  425.                     if(--att_ptr->ready[n-1]->shotscur<1) {
  426.                         print(fd, 
  427.                              "Your %s fell apart.\n", 
  428.                              att_ptr->ready[n-1]->name);
  429.                         broadcast_rom(fd, 
  430.                              att_ptr->rom_num,
  431.                              "%M's %s fell apart.",
  432.                              att_ptr,
  433.                              att_ptr->ready[n-1]->name);
  434.                         add_obj_crt(att_ptr->ready[n-1],
  435.                                 att_ptr);
  436.                         att_ptr->ready[n-1] = 0;
  437.                         compute_ac(att_ptr);
  438.                     }
  439.                 }
  440.                 
  441.                 if(t - Ply[att_ptr->fd].io->ltime > 5L &&
  442.                    crt_ptr->NUMHITS > 1 && !F_ISSET(att_ptr,PNOAAT) && !p) {
  443.                     rtn = attack_crt(att_ptr, crt_ptr);
  444.                     if(rtn) {
  445.                         cp = first_active;
  446.                         continue;
  447.                     }
  448.                 }
  449.  
  450.                 if(att_ptr->hpcur < 1) {
  451.                     ANSI(fd, MAGENTA);
  452.                     print(fd, "%M killed you.\n", crt_ptr);
  453.                     ANSI(fd, WHITE);
  454.                     die(att_ptr, crt_ptr);
  455.                     cp = first_active;
  456.                     continue;
  457.                 }
  458.     
  459.                 else if(F_ISSET(att_ptr, PWIMPY)) {
  460.                     if(att_ptr->hpcur <= att_ptr->WIMPYVALUE) {
  461.                         flee(att_ptr);
  462.                         cp = first_active;
  463.                         continue;
  464.                     }
  465.                 }
  466.             
  467.                 else if(F_ISSET(att_ptr, PFEARS)) {
  468.                     int ff;
  469.                     ff = 40 + (1- (att_ptr->hpcur/att_ptr->hpmax))*40 +
  470.                         bonus[att_ptr->constitution]*3 + 
  471.                         (att_ptr->class == PALADIN) ? -10 : 0;
  472.                     if(ff < mrand(1,100)) {
  473.                         flee(att_ptr);
  474.                         cp = first_active;
  475.                         continue;
  476.                     }
  477.                 }
  478.             }
  479.  
  480.             else if(n <= 20 && !p) {
  481.                 ANSI(att_ptr->fd, CYAN);
  482.                 print(att_ptr->fd, "%M missed you.\n", crt_ptr);
  483.                 ANSI(att_ptr->fd, WHITE);
  484.                 if(t - Ply[att_ptr->fd].io->ltime > 5L &&
  485.                    crt_ptr->NUMHITS > 1) {
  486.                     rtn = attack_crt(att_ptr, crt_ptr);
  487.                     if(rtn) {
  488.                         cp = first_active;
  489.                         continue;
  490.                     }
  491.                 }
  492.             }
  493.             cp = cp->next_tag;
  494.             continue;
  495.         }
  496.         }
  497.  
  498.         if(F_ISSET(crt_ptr, MAGGRE) || F_ISSET(crt_ptr, MGAGGR) ||
  499.         F_ISSET(crt_ptr, MEAGGR)) {
  500.     if (F_ISSET(crt_ptr, MAGGRE))
  501.                att_ptr = lowest_piety(rom_ptr, F_ISSET(crt_ptr, MDINVI) ? 1:0);
  502.             else {
  503.                 att_ptr = low_piety_alg(rom_ptr,
  504.                     F_ISSET(crt_ptr, MDINVI) ? 1:0,
  505.                     F_ISSET(crt_ptr,MGAGGR) ? -1 : 1,crt_ptr->level);
  506. }
  507.  
  508.             if(!att_ptr) {
  509.                 cp = cp->next_tag;
  510.                 continue;
  511.             }
  512.             ANSI(att_ptr->fd, RED);
  513.             print(att_ptr->fd, "%M attacks you.\n", crt_ptr);
  514.             ANSI(att_ptr->fd, WHITE);
  515.             crt_ptr->lasttime[LT_ATTCK].interval = 0;
  516.             broadcast_rom(att_ptr->fd, att_ptr->rom_num, 
  517.                       "%M attacks %m.",
  518.                       crt_ptr, att_ptr);
  519.             add_enm_crt(att_ptr->name, crt_ptr); 
  520.         }
  521.  
  522.         cp = cp->next_tag;
  523.  
  524.     }
  525. }
  526.  
  527. /************************************************************************/
  528. /*              choose_item             */
  529. /************************************************************************/
  530.  
  531. /* This function randomly chooses an item that the player pointed to    */
  532. /* by the first argument is wearing.                    */
  533.  
  534. int choose_item(ply_ptr)
  535. creature    *ply_ptr;
  536. {
  537.     char    checklist[MAXWEAR];
  538.     int numwear=0, i;
  539.  
  540.     for(i=0; i<MAXWEAR; i++) {
  541.         checklist[i] = 0;
  542.         if(i==WIELD-1 || i==HELD-1) continue;
  543.         if(ply_ptr->ready[i])
  544.             checklist[numwear++] = i+1;
  545.     }
  546.  
  547.     if(!numwear) return(0);
  548.  
  549.     i = mrand(0, numwear-1);
  550.     return(checklist[i]);
  551. }
  552.  
  553. /**********************************************************************/
  554. /*              crt_spell                 */
  555. /**********************************************************************/
  556.  
  557. /* This function allows monsters to cast spells at players.       */
  558.  
  559. int crt_spell(crt_ptr, att_ptr)
  560. creature    *crt_ptr;
  561. creature    *att_ptr;
  562. {
  563.     cmd cmnd;
  564.     int i, j, spl, c;
  565.     int known[10], knowctr = 0;
  566.     int (*fn)();
  567.  
  568.     for(i=0; i<16; i++) {
  569.         if(!crt_ptr->spells[i]) continue;
  570.         for(j=i*8; j<=(i*8+7); j++) {
  571.             if(knowctr > 9) break;
  572.             if(S_ISSET(crt_ptr, j))
  573.                 known[knowctr++] = j;
  574.         }
  575.         if(knowctr > 9) break;
  576.     }
  577.  
  578.     if(!knowctr)
  579.         spl = 1;
  580.     else {
  581.         i = mrand(1, knowctr);
  582.         spl = known[i-1];
  583.     }
  584.  
  585.     if ((spllist[spl].splno != SVIGOR) && 
  586.         (spllist[spl].splno != SMENDW) &&
  587.         (spllist[spl].splno != SFHEAL)){
  588.         strcpy(cmnd.str[2], att_ptr->name);
  589.         cmnd.val[2] = 1;
  590.         cmnd.num = 3;
  591.     } else
  592.          cmnd.num = 2;
  593.  
  594.     fn = spllist[spl].splfn;
  595.  
  596.     ANSI(att_ptr->fd, RED);
  597.     if(fn == offensive_spell) {
  598.         for(c=0; ospell[c].splno != spllist[spl].splno; c++)
  599.             if(ospell[c].splno == -1) return(0);
  600.         i = (*fn)(crt_ptr, &cmnd, CAST, spllist[spl].splstr,
  601.             &ospell[c]);
  602.     }
  603.     else i = (*fn)(crt_ptr, &cmnd, CAST);
  604.     ANSI(att_ptr->fd, WHITE);
  605.     return(i);
  606. }
  607.  
  608. /**********************************************************************/
  609. /*              update_time               */
  610. /**********************************************************************/
  611.  
  612. /* This function updates the game time in hours.  When it is 6am a sunrise */
  613. /* message is broadcast.  When it is 8pm a sunset message is broadcast.    */
  614.  
  615. void update_time(t)
  616. long    t;
  617. {
  618.     int daytime;
  619.  
  620.     last_time_update = t;
  621.  
  622.     Time++;
  623.     daytime = (int)(Time % 24L);
  624.  
  625.     if(daytime == 6)
  626.         broadcast("The sun rises.");
  627.     else if(daytime == 20)
  628.         broadcast("The sun disappears over the horizon.");
  629.  
  630. }
  631.  
  632. /**********************************************************************/
  633. /*              update_shutdown               */
  634. /**********************************************************************/
  635.  
  636. /* This function broadcasts a shutdown message every 30 seconds until */
  637. /* shutdown is achieved.  Then it saves off all rooms and players,    */
  638. /* and exits the game.                            */
  639.  
  640. void update_shutdown(t)
  641. long t;
  642. {
  643.     long    i;
  644.      char path[128];
  645.  
  646.     last_shutdown_update = t;
  647.  
  648.     i = Shutdown.ltime + Shutdown.interval;
  649.     if(i > t) {
  650.         if(i-t > 60)
  651.             broadcast("### Game shutdown in %d:%02d minutes.", 
  652.                   (i-t)/60L, (i-t)%60L);
  653.         else
  654.             broadcast("### Game shutdown in %d seconds.", i-t);
  655.     }
  656.     else {
  657.         broadcast("### Shutting down now.");
  658.         output_buf();
  659.         logf("--- Game shut down ---\n");
  660.         resave_all_rom(1);
  661.         save_all_ply();
  662.  
  663.  
  664. #ifdef RECORD_ALL
  665.     sprintf(path,"%s/%s",LOGPATH,"all_cmd");
  666.     unlink(path);
  667. #endif RECORD_ALL
  668.     kill(getpid(), 9);
  669.         exit(0);
  670.     }
  671. }
  672.  
  673. /**********************************************************************/
  674. /*              add_active                */
  675. /**********************************************************************/
  676.  
  677. /* This function adds a monster to the active-monster list.  A pointer */
  678. /* to the monster is passed in the first parameter.            */
  679.  
  680. void add_active(crt_ptr)
  681. creature    *crt_ptr;
  682. {
  683.     ctag    *cp, *ct;
  684.  
  685.     del_active(crt_ptr);
  686.     if(!crt_ptr)
  687.         return;
  688.  
  689.     ct = (ctag *)malloc(sizeof(ctag));
  690.     if(!ct)
  691.         merror("add_active", FATAL);
  692.  
  693.     ct->crt = crt_ptr;
  694.     ct->next_tag = 0;
  695.  
  696.     if(!first_active)
  697.         first_active = ct;
  698.     else {
  699.         ct->next_tag = first_active;
  700.         first_active = ct;
  701.     }
  702.  
  703. }
  704.  
  705. /**********************************************************************/
  706. /*              del_active                */
  707. /**********************************************************************/
  708.  
  709. /* This function removes a monster from the active-monster list.  The */
  710. /* parameter contains a pointer to the monster which is to be removed */
  711.  
  712. void del_active(crt_ptr)
  713. creature    *crt_ptr;
  714. {
  715.     ctag    *cp, *prev;
  716.  
  717.     if(!(cp = first_active)) return;
  718.     if(cp->crt == crt_ptr) {
  719.         first_active = cp->next_tag;
  720.         free(cp);
  721.         return;
  722.     }
  723.  
  724.     prev = cp;
  725.     cp = cp->next_tag;
  726.     while(cp) {
  727.         if(cp->crt == crt_ptr) {
  728.             prev->next_tag = cp->next_tag;
  729.             free(cp);
  730.             return;
  731.         }
  732.         prev = cp;
  733.         cp = cp->next_tag;
  734.     }
  735.  
  736. }
  737. /*===================================================================*/
  738. /*              update_exit              */
  739. /*===================================================================*/
  740. void update_exit(t)
  741. long    t;
  742. {
  743. room    *rom_ptr;
  744. xtag    *xp;
  745. char    *tmp;
  746. int i,x;
  747.  
  748.     last_exit_update = t;
  749.     for(i=0;i<MAX_TEXIT; i++){
  750.         if(load_rom( time_x[i].room,&rom_ptr) < 0)
  751.             return; 
  752.         xp = rom_ptr->first_ext;
  753.         while(xp){
  754.             if((time_x[i].name1) && (time_x[i].exit1 == xp->ext->room)
  755.           && (!strcmp(xp->ext->name,time_x[i].name1))) 
  756.                 F_SET(xp->ext,XNOSEE);
  757.  
  758.             if((time_x[i].name2) && (time_x[i].exit2 == xp->ext->room)
  759.           && (!strcmp(xp->ext->name,time_x[i].name2))) 
  760.                 F_CLR(xp->ext,XNOSEE);
  761.  
  762.             xp = xp->next_tag;
  763.         }
  764.  
  765.              tmp  = time_x[i].name1;
  766.              x = time_x[i].exit1;
  767.              time_x[i].name1 = time_x[i].name2;
  768.              time_x[i].exit1 = time_x[i].exit2;
  769.              time_x[i].name2 = tmp;
  770.              time_x[i].exit2 = x;
  771.        
  772.              if (!t_toggle)
  773.                tmp = time_x[i].mess1;  
  774.              else
  775.                tmp = time_x[i].mess2;  
  776.  
  777.             if (tmp)
  778.                 broadcast("\n%s",tmp);
  779.             t_toggle = !t_toggle;
  780.                     
  781.      }
  782. }
  783.  
  784. /*====================================================================*/
  785.  
  786. void update_allcmd(t)
  787. long t;
  788. {
  789.     char path[128];
  790.  
  791.     last_allcmd = t;
  792.     sprintf(path,"%s/%s",LOGPATH,"all_cmd");
  793.     unlink(path);
  794. }
  795.  
  796. /*************************************/
  797. int list_act(ply_ptr, cmnd)
  798. creature *ply_ptr;
  799. cmd    *cmnd;
  800.  
  801. {
  802. ctag    *cp;
  803.  
  804. if (ply_ptr->class < DM)
  805.     return(0);
  806. print(ply_ptr->fd,"Active monster list\n");
  807.     cp = first_active;
  808.     
  809.     while(cp){
  810.     print(ply_ptr->fd,"Name:%s.\n",cp->crt->name);
  811.     cp = cp->next_tag;
  812.     }
  813. output_buf();
  814. return;
  815. }
  816.